'use client';

import { useEffect, useState } from 'react';
import UnauthorizedPage from '@/app/[locale]/401/unauthorized';
import DeniedPage from '@/app/[locale]/403/denied';
import { clientClearToken, clientRefreshToken } from '@/services/api';
import { useMutation } from '@tanstack/react-query';
import NotFoundPage from '@/app/[locale]/notfound/notfound';
import DefaultErrorPage from '@/app/[locale]/common/error/default';
import { parseJSON } from '@/lib/tool';

const DEFAULT_INFO = {
  message: 'Unknown Error',
  status: 500,
  code: 0,
};

const UNAUTHORIZED_STATUS = 401;
const FORBIDDEN_STATUS = 403;
const NOT_FOUND_STATUS = 404;
const UNAUTHORIZED_CODE0 = 4010;
const UNAUTHORIZED_CODE1 = 4011;

export default function ResetPage({
  error,
  reset,
}: {
  error: string | (Error & { digest?: string });
  reset?: () => void;
}) {
  const [errorDetails, setErrorDetails] = useState(DEFAULT_INFO);
  const [isLoading, setIsLoading] = useState(true);

  const clientClearTokenMutation = useMutation(clientClearToken);
  const clientRefreshTokenMutation = useMutation(clientRefreshToken);

  useEffect(() => {
    let info = {
      ...DEFAULT_INFO,
      digest: typeof error === 'string' ? '' : error.digest,
    };

    if (error instanceof Error) {
      const json = parseJSON(error.message);
      if (json) {
        info = {
          ...info,
          ...json,
        };
      } else {
        info.message = error.message;
      }
    } else {
      const json = parseJSON(error);
      if (json) {
        info = {
          ...info,
          ...json,
        };
      } else {
        info.message = error;
      }
    }

    if (!info.message) {
      info.message = DEFAULT_INFO.message;
    }

    setErrorDetails(info);
    setIsLoading(false);
  }, [error]);

  useEffect(() => {
    const { status, code } = errorDetails;
    if (status === UNAUTHORIZED_STATUS && code === UNAUTHORIZED_CODE1) {
      clientClearTokenMutation.mutateAsync({});
    } else if (status === UNAUTHORIZED_STATUS && code === UNAUTHORIZED_CODE0) {
      clientRefreshTokenMutation.mutateAsync({});
    }
  }, [errorDetails]);

  const isErrorStatus = [
    UNAUTHORIZED_STATUS,
    FORBIDDEN_STATUS,
    NOT_FOUND_STATUS,
  ].includes(errorDetails.status);

  return (
    <>
      {isErrorStatus && errorDetails.status === UNAUTHORIZED_STATUS && (
        <UnauthorizedPage />
      )}
      {isErrorStatus && errorDetails.status === FORBIDDEN_STATUS && (
        <DeniedPage />
      )}
      {isErrorStatus && errorDetails.status === NOT_FOUND_STATUS && (
        <NotFoundPage />
      )}
      {!isErrorStatus && (
        <DefaultErrorPage
          isLoading={isLoading}
          errorDetails={errorDetails}
          reset={reset}
        />
      )}
    </>
  );
}
